-module(state_storage).
-include("definitions.hrl").

-export([start/1, stop/0, updateState/1, flush/0, init/0, getCurrentStates/0]).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                   интерфейсные
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%-define(TABLE_STATE_PATH, "D:\\tableForState.txt").
start(Pid) ->
  true = register(stateStorage, spawn(state_storage, init, [])).

init() ->
  Tab = ets:new(stateTable, [named_table, {keypos, #stateRecord.id}]),
  loopEvent(Tab)
.



updateState(State) ->
  case whereis(stateStorage) of
    undefined -> ok;
    Pid -> Pid ! {update, State, self()}
  end.

getCurrentStates() ->
  case whereis(stateStorage) of
    undefined -> ok;
    Pid -> Pid ! {getCurrentState, self()},
      receive
        States when is_list(States) ->
          States
      end
  end.

stop() ->
  io:format("stateStorage finished~n"),
  stateStorage ! stop.

%неблокирующая
% а стала блокирующая
flush() ->
  stateStorage ! {flush, self()},
  receive
    {ok, flushed} -> ok
  end.

loopEvent(Tab) ->
  receive
    stop ->
      flushToMnesia(),
      ok;
    {flush, Pid} ->
      ok = flushToMnesia(),
      Pid ! {ok, flushed},
      loopEvent(Tab);
    {update, State, From} ->
      ets:insert(stateTable, State),
      ok = flushToMnesia(),
      %From ! ok,
      loopEvent(Tab);
    {getCurrentState, From} ->
      States = getAll(),
      From ! States,
      loopEvent(Tab)
  end.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                   реализация
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

flushToMnesia() ->
  States = getAll(),
  flushItems(States).

flushItems([]) ->
  %ets:delete_all_objects(stateTable),
  ok;
flushItems([State | States]) ->
  test_storage:updateState(State),
  flushItems(States)
.

getAll() ->
  lists:flatten(ets:match(stateTable, '$1')).